package com.smartleanx.module.hrm.util.RestUtil;

import org.apache.http.client.HttpClient;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

@Configuration
public class RestTemplateConfig
{
    /**
     * http连接管理器
     *
     * @return
     */

    @Bean

    public HttpClientConnectionManager poolingHttpClientConnectionManager() {

        // 注册http和https请求

        Registry registry = RegistryBuilder.create()

                .register("http", PlainConnectionSocketFactory.getSocketFactory())

                .register("https", SSLConnectionSocketFactory.getSocketFactory())

                .build();

        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
                new PoolingHttpClientConnectionManager(registry);
        // 可以用默认的

        // PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new
        // PoolingHttpClientConnectionManager();

        // 最大连接数

        poolingHttpClientConnectionManager.setMaxTotal(500);

        // 同路由并发数（每个主机的并发）

        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);

        return poolingHttpClientConnectionManager;

    }

    /**
     * HttpClient
     *
     * @param poolingHttpClientConnectionManager
     * @return
     */

    @Bean

    public HttpClient httpClient(HttpClientConnectionManager poolingHttpClientConnectionManager) {

        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();

        // 设置http连接管理器

        httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);

        // 设置重试次数

        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true));

        return httpClientBuilder.build();

    }

    /**
     * 请求连接池配置
     *
     * @param httpClient
     * @return
     */

    @Bean

    public ClientHttpRequestFactory clientHttpRequestFactory(HttpClient httpClient) {

        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();

        // httpClient创建器

        clientHttpRequestFactory.setHttpClient(httpClient);

        // 连接超时时间/毫秒（连接上服务器(握手成功)的时间，超出抛出connect timeout）

        clientHttpRequestFactory.setConnectTimeout(5 * 1000);

        // 数据读取超时时间(socketTimeout)/毫秒（务器返回数据(response)的时间，超过抛出read timeout）

        clientHttpRequestFactory.setReadTimeout(10 * 1000);

        // 连接池获取请求连接的超时时间，不宜过长，必须设置/毫秒（超时间未拿到可用连接，会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout
        // waiting for connection from pool）

        clientHttpRequestFactory.setConnectionRequestTimeout(10 * 1000);

        return clientHttpRequestFactory;

    }

    /**
     * rest模板
     *
     * @return
     */

    @Bean

    public RestTemplate restTemplate(ClientHttpRequestFactory clientHttpRequestFactory) {

        // boot中可使用RestTemplateBuilder.build创建

        RestTemplate restTemplate = new RestTemplate();

        // 配置请求工厂

        restTemplate.setRequestFactory(clientHttpRequestFactory);

        // 配置统一请求头
        List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
        interceptors.add(new HeaderRequestInterceptor("Content-Type", "application/json;charset=UTF-8"));
        restTemplate.setInterceptors(interceptors);

        return restTemplate;

    }
}
